using MauiBuilder.Models;
using Microsoft.Extensions.Logging;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Xml.Linq;

namespace MauiBuilder.Services;

/// <summary>
/// 微信支付服务实现
/// </summary>
public class WeChatPayService : IWeChatPayService
{
    private PaymentConfig? _config;
    private readonly ILogger<WeChatPayService> _logger;
    
    /// <summary>
    /// 支付类型
    /// </summary>
    public PaymentType PaymentType => PaymentType.WeChatPay;
    
    /// <summary>
    /// 是否支持当前平台
    /// </summary>
    public bool IsSupportedPlatform => DeviceInfo.Current.Platform == DevicePlatform.Android || 
                                       DeviceInfo.Current.Platform == DevicePlatform.iOS;

    public WeChatPayService(ILogger<WeChatPayService> logger)
    {
        _logger = logger;
    }

    /// <summary>
    /// 初始化支付配置
    /// </summary>
    public async Task InitializeAsync(PaymentConfig config)
    {
        _config = config ?? throw new ArgumentNullException(nameof(config));
        
        if (string.IsNullOrEmpty(_config.AppId))
            throw new ArgumentException("微信AppId不能为空");
        
        if (string.IsNullOrEmpty(_config.MerchantId))
            throw new ArgumentException("微信商户号不能为空");
        
        if (string.IsNullOrEmpty(_config.PrivateKey))
            throw new ArgumentException("微信API密钥不能为空");
        
        _logger.LogInformation("微信支付服务初始化完成，AppId: {AppId}, MerchantId: {MerchantId}", 
            _config.AppId, _config.MerchantId);
        
        await Task.CompletedTask;
    }

    /// <summary>
    /// 创建支付订单
    /// </summary>
    public async Task<PaymentResponse> CreatePaymentAsync(PaymentRequest request)
    {
        try
        {
            if (_config == null)
                throw new InvalidOperationException("微信支付服务未初始化");

            _logger.LogInformation("创建微信支付订单，订单号: {OrderId}, 金额: {Amount}", 
                request.OrderId, request.Amount);

            // 构建统一下单参数
            var parameters = new Dictionary<string, string>
            {
                { "appid", _config.AppId },
                { "mch_id", _config.MerchantId },
                { "nonce_str", GenerateNonceStr() },
                { "body", request.Subject },
                { "detail", request.Body },
                { "out_trade_no", request.OrderId },
                { "total_fee", ((int)request.Amount).ToString() }, // 微信支付金额单位为分
                { "spbill_create_ip", "127.0.0.1" }, // 实际应用中应获取真实IP
                { "trade_type", "APP" },
                { "time_expire", DateTime.Now.AddMinutes(request.TimeoutMinutes).ToString("yyyyMMddHHmmss") }
            };

            // 添加回调URL
            if (!string.IsNullOrEmpty(request.NotifyUrl))
                parameters.Add("notify_url", request.NotifyUrl);

            // 生成签名
            var sign = GenerateSign(parameters, _config.PrivateKey);
            parameters.Add("sign", sign);

            // 构建XML请求
            var xmlRequest = BuildXmlRequest(parameters);

            // 调用统一下单接口
            var response = await CallUnifiedOrderAsync(xmlRequest);

            if (response.IsSuccess && !string.IsNullOrEmpty(response.PaymentData))
            {
                // 构建APP支付参数
                var appPayData = BuildAppPayData(response.PaymentData);
                response.PaymentData = appPayData;
            }

            return response;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "创建微信支付订单失败");
            return new PaymentResponse
            {
                IsSuccess = false,
                OrderId = request.OrderId,
                Status = PaymentStatus.Failed,
                ErrorMessage = ex.Message,
                ErrorCode = "CREATE_ORDER_FAILED"
            };
        }
    }

    /// <summary>
    /// 查询支付结果
    /// </summary>
    public async Task<PaymentResult> QueryPaymentAsync(string orderId)
    {
        try
        {
            if (_config == null)
                throw new InvalidOperationException("微信支付服务未初始化");

            _logger.LogInformation("查询微信支付结果，订单号: {OrderId}", orderId);

            var parameters = new Dictionary<string, string>
            {
                { "appid", _config.AppId },
                { "mch_id", _config.MerchantId },
                { "out_trade_no", orderId },
                { "nonce_str", GenerateNonceStr() }
            };

            var sign = GenerateSign(parameters, _config.PrivateKey);
            parameters.Add("sign", sign);

            var xmlRequest = BuildXmlRequest(parameters);

            // 这里应该调用微信支付查询接口
            // 由于是演示代码，这里返回模拟结果
            await Task.Delay(1000); // 模拟网络请求

            return new PaymentResult
            {
                IsSuccess = true,
                OrderId = orderId,
                Status = PaymentStatus.Success,
                Message = "支付成功",
                PayTime = DateTime.Now
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "查询微信支付结果失败");
            return new PaymentResult
            {
                IsSuccess = false,
                OrderId = orderId,
                Status = PaymentStatus.Failed,
                Message = ex.Message
            };
        }
    }

    /// <summary>
    /// 取消支付
    /// </summary>
    public async Task<bool> CancelPaymentAsync(string orderId)
    {
        try
        {
            if (_config == null)
                throw new InvalidOperationException("微信支付服务未初始化");

            _logger.LogInformation("取消微信支付，订单号: {OrderId}", orderId);

            // 这里应该调用微信支付关闭订单接口
            await Task.Delay(500); // 模拟网络请求

            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "取消微信支付失败");
            return false;
        }
    }

    /// <summary>
    /// 验证支付回调
    /// </summary>
    public async Task<PaymentResult> VerifyCallbackAsync(Dictionary<string, string> callbackData)
    {
        try
        {
            if (_config == null)
                throw new InvalidOperationException("微信支付服务未初始化");

            _logger.LogInformation("验证微信支付回调");

            // 验证签名
            var sign = callbackData.GetValueOrDefault("sign", "");
            var calculatedSign = GenerateSign(callbackData.Where(p => p.Key != "sign").ToDictionary(p => p.Key, p => p.Value), _config.PrivateKey);

            if (sign != calculatedSign)
            {
                return new PaymentResult
                {
                    IsSuccess = false,
                    Status = PaymentStatus.Failed,
                    Message = "签名验证失败"
                };
            }

            var returnCode = callbackData.GetValueOrDefault("return_code", "");
            var resultCode = callbackData.GetValueOrDefault("result_code", "");
            var orderId = callbackData.GetValueOrDefault("out_trade_no", "");
            var totalFee = callbackData.GetValueOrDefault("total_fee", "0");

            var isSuccess = returnCode == "SUCCESS" && resultCode == "SUCCESS";
            var status = isSuccess ? PaymentStatus.Success : PaymentStatus.Failed;

            await Task.CompletedTask;

            return new PaymentResult
            {
                IsSuccess = isSuccess,
                OrderId = orderId,
                Status = status,
                Amount = decimal.TryParse(totalFee, out var amount) ? amount : 0,
                PayTime = isSuccess ? DateTime.Now : null,
                Message = isSuccess ? "支付成功" : callbackData.GetValueOrDefault("err_code_des", "支付失败"),
                RawData = JsonSerializer.Serialize(callbackData)
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "验证微信支付回调失败");
            return new PaymentResult
            {
                IsSuccess = false,
                Status = PaymentStatus.Failed,
                Message = ex.Message
            };
        }
    }

    /// <summary>
    /// 注册微信支付
    /// </summary>
    public async Task<bool> RegisterWeChatPayAsync(string appId)
    {
        try
        {
            _logger.LogInformation("注册微信支付，AppId: {AppId}", appId);

            // 这里应该调用微信SDK注册接口
            // 由于是演示代码，直接返回成功
            await Task.Delay(100);

            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "注册微信支付失败");
            return false;
        }
    }

    /// <summary>
    /// 检查微信是否安装
    /// </summary>
    public async Task<bool> IsWeChatInstalledAsync()
    {
        try
        {
            // 这里应该检查设备是否安装了微信
            // 由于是演示代码，根据平台返回模拟结果
            await Task.Delay(50);

            if (DeviceInfo.Current.Platform == DevicePlatform.Android)
            {
                // Android平台检查微信是否安装
                return true; // 模拟已安装
            }
            else if (DeviceInfo.Current.Platform == DevicePlatform.iOS)
            {
                // iOS平台检查微信是否安装
                return true; // 模拟已安装
            }

            return false;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "检查微信安装状态失败");
            return false;
        }
    }

    /// <summary>
    /// 处理微信支付回调
    /// </summary>
    public async Task<PaymentResult> HandleWeChatPayResultAsync(Dictionary<string, object> result)
    {
        try
        {
            _logger.LogInformation("处理微信支付结果");

            var errCode = result.GetValueOrDefault("errCode", "").ToString();
            var orderId = result.GetValueOrDefault("out_trade_no", "").ToString();

            var status = errCode switch
            {
                "0" => PaymentStatus.Success,
                "-1" => PaymentStatus.Failed,
                "-2" => PaymentStatus.Cancelled,
                "-3" => PaymentStatus.Failed,
                "-4" => PaymentStatus.Failed,
                "-5" => PaymentStatus.Failed,
                _ => PaymentStatus.Failed
            };

            await Task.CompletedTask;

            return new PaymentResult
            {
                IsSuccess = status == PaymentStatus.Success,
                OrderId = orderId,
                Status = status,
                PayTime = status == PaymentStatus.Success ? DateTime.Now : null,
                Message = GetWeChatPayStatusMessage(errCode),
                RawData = JsonSerializer.Serialize(result)
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "处理微信支付结果失败");
            return new PaymentResult
            {
                IsSuccess = false,
                Status = PaymentStatus.Failed,
                Message = ex.Message,
                RawData = JsonSerializer.Serialize(result)
            };
        }
    }

    #region 私有方法

    /// <summary>
    /// 生成随机字符串
    /// </summary>
    private string GenerateNonceStr()
    {
        return Guid.NewGuid().ToString("N");
    }

    /// <summary>
    /// 生成签名
    /// </summary>
    private string GenerateSign(Dictionary<string, string> parameters, string key)
    {
        // 排序参数
        var sortedParams = parameters
            .Where(p => !string.IsNullOrEmpty(p.Value) && p.Key != "sign")
            .OrderBy(p => p.Key)
            .ToList();

        // 构建待签名字符串
        var signString = string.Join("&", sortedParams.Select(p => $"{p.Key}={p.Value}"));
        signString += $"&key={key}";

        // MD5签名
        using var md5 = MD5.Create();
        var hashBytes = md5.ComputeHash(Encoding.UTF8.GetBytes(signString));
        return BitConverter.ToString(hashBytes).Replace("-", "").ToUpper();
    }

    /// <summary>
    /// 构建XML请求
    /// </summary>
    private string BuildXmlRequest(Dictionary<string, string> parameters)
    {
        var xml = new XElement("xml");
        foreach (var param in parameters)
        {
            xml.Add(new XElement(param.Key, new XCData(param.Value)));
        }
        return xml.ToString();
    }

    /// <summary>
    /// 调用统一下单接口
    /// </summary>
    private async Task<PaymentResponse> CallUnifiedOrderAsync(string xmlRequest)
    {
        try
        {
            // 这里应该调用微信统一下单接口
            // 由于是演示代码，返回模拟响应
            await Task.Delay(1000); // 模拟网络请求

            // 模拟成功响应
            var prepayId = $"wx{DateTime.Now:yyyyMMddHHmmss}{new Random().Next(1000, 9999)}";

            return new PaymentResponse
            {
                IsSuccess = true,
                Status = PaymentStatus.Pending,
                PaymentData = prepayId, // 这里应该是prepay_id
                CreateTime = DateTime.Now
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "调用微信统一下单接口失败");
            return new PaymentResponse
            {
                IsSuccess = false,
                Status = PaymentStatus.Failed,
                ErrorMessage = ex.Message,
                ErrorCode = "UNIFIED_ORDER_FAILED"
            };
        }
    }

    /// <summary>
    /// 构建APP支付数据
    /// </summary>
    private string BuildAppPayData(string prepayId)
    {
        if (_config == null)
            throw new InvalidOperationException("微信支付服务未初始化");

        var timestamp = DateTimeOffset.Now.ToUnixTimeSeconds().ToString();
        var nonceStr = GenerateNonceStr();
        var packageValue = $"Sign=WXPay";

        var parameters = new Dictionary<string, string>
        {
            { "appid", _config.AppId },
            { "partnerid", _config.MerchantId },
            { "prepayid", prepayId },
            { "package", packageValue },
            { "noncestr", nonceStr },
            { "timestamp", timestamp }
        };

        var sign = GenerateSign(parameters, _config.PrivateKey);

        var appPayData = new
        {
            appid = _config.AppId,
            partnerid = _config.MerchantId,
            prepayid = prepayId,
            package = packageValue,
            noncestr = nonceStr,
            timestamp = timestamp,
            sign = sign
        };

        return JsonSerializer.Serialize(appPayData);
    }

    /// <summary>
    /// 获取微信支付状态消息
    /// </summary>
    private string GetWeChatPayStatusMessage(string errCode)
    {
        return errCode switch
        {
            "0" => "支付成功",
            "-1" => "支付错误",
            "-2" => "用户取消",
            "-3" => "发送失败",
            "-4" => "授权失败",
            "-5" => "微信不支持",
            _ => "未知错误"
        };
    }

    #endregion
}